//
//  V2DataManager.m
//  V2EX
//
//  Created by CYT on 16/6/12.
//  Copyright © 2016年 Chris. All rights reserved.
//

#import "V2DataManager.h"
#import <AFNetworking.h>
#import "HTMLParser.h"
#import <RegexKitLite.h>


typedef NS_ENUM(NSInteger, V2RequestMethod) {
    V2RequestMethodJSONGET    = 1,
    V2RequestMethodHTTPPOST   = 2,
    V2RequestMethodHTTPGET    = 3,
    V2RequestMethodHTTPGETPC  = 4
};


@interface V2DataManager ()

//@property (nonatomic, readwrite, strong) V2UserModel *user;


@property (nonatomic, strong) AFHTTPSessionManager *manager;

@property (nonatomic, copy) NSString *userAgentMobile;
@property (nonatomic, copy) NSString *userAgentPC;

@end

@implementation V2DataManager

- (instancetype)init {
    if (self = [super init]) {
        
        
        UIWebView *webView = [[UIWebView alloc]initWithFrame:CGRectZero];
        self.userAgentMobile = [webView stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
        self.userAgentPC = @"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/537.75.14";
        
        self.preferHttps = YES;
    }
    return self;
}


//使用HTTPS
- (void)setPreferHttps:(BOOL)preferHttps {
    _preferHttps = preferHttps;
    
    NSURL *baseUrl;
    
    if (preferHttps) {
        baseUrl = [NSURL URLWithString:@"https://www.v2ex.com"];
    } else {
        baseUrl = [NSURL URLWithString:@"http://www.v2ex.com"];
    }

    self.manager = [[AFHTTPSessionManager alloc] initWithBaseURL:baseUrl];
    AFHTTPRequestSerializer* serializer = [AFHTTPRequestSerializer serializer];
    self.manager.requestSerializer = serializer;
}


/**
 *  单例
 */
+ (instancetype)manager {
    static V2DataManager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[V2DataManager alloc] init];
    });
    return manager;
}



- (NSURLSessionDataTask *)requestWithMethod:(V2RequestMethod)method
                                  URLString:(NSString *)URLString
                                 parameters:(NSDictionary *)parameters
                                    success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
                                    failure:(void (^)(NSError *error))failure  {
    // stateBar
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
    
    // Handle Common Mission, Cache, Data Reading & etc.
    void (^responseHandleBlock)(NSURLSessionDataTask *task, id responseObject) = ^(NSURLSessionDataTask *task, id responseObject) {
        
        [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
        
        // Any common handler for Response
        
        //        NSLog(@"URL:\n%@", [task.currentRequest URL].absoluteString);
        
        
        success(task, responseObject);
        
    };
    
    // Create HTTPSession
    NSURLSessionDataTask *task = nil;
    
    [self.manager.requestSerializer setValue:self.userAgentMobile forHTTPHeaderField:@"User-Agent"];
    
    if (method == V2RequestMethodJSONGET) {
        AFHTTPResponseSerializer *responseSerializer = [AFJSONResponseSerializer serializer];
        self.manager.responseSerializer = responseSerializer;
        task = [self.manager GET:URLString parameters:parameters progress:nil success:^(NSURLSessionDataTask *task, id responseObject) {
            responseHandleBlock(task, responseObject);
        } failure:^(NSURLSessionDataTask *task, NSError *error) {
            V2Log(@"Error: \n%@", [error description]);
            [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
            failure(error);
        }];
    }
    if (method == V2RequestMethodHTTPGET) {
        AFHTTPResponseSerializer *responseSerializer = [AFHTTPResponseSerializer serializer];
        self.manager.responseSerializer = responseSerializer;
        task = [self.manager GET:URLString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            responseHandleBlock(task, responseObject);
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
            failure(error);
        }];
                
    }
    if (method == V2RequestMethodHTTPPOST) {
        AFHTTPResponseSerializer *responseSerializer = [AFHTTPResponseSerializer serializer];
        self.manager.responseSerializer = responseSerializer;
        task = [self.manager POST:URLString parameters:parameters progress:nil success:^(NSURLSessionDataTask *task, id responseObject) {
            responseHandleBlock(task, responseObject);
        } failure:^(NSURLSessionDataTask *task, NSError *error) {
            [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
            failure(error);
        }];
    }
    if (method == V2RequestMethodHTTPGETPC) {
        AFHTTPResponseSerializer *responseSerializer = [AFHTTPResponseSerializer serializer];
        self.manager.responseSerializer = responseSerializer;
        [self.manager.requestSerializer setValue:self.userAgentPC forHTTPHeaderField:@"User-Agent"];
        task = [self.manager GET:URLString parameters:parameters progress:nil success:^(NSURLSessionDataTask *task, id responseObject) {
            responseHandleBlock(task, responseObject);
        } failure:^(NSURLSessionDataTask *task, NSError *error) {
            [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
            failure(error);
        }];
    }
    
    return task;
}

#pragma mark - Public Request Methods - GET
- (NSURLSessionDataTask *)getMemberNodeListSuccess:(void (^)(NSArray *list))success
                                           failure:(void (^)(NSError *error))failure {
    
    NSString *urlString = @"my/nodes";
    
    [self requestWithMethod:V2RequestMethodHTTPGET URLString:urlString parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {
        
        NSArray *list = [self getNodeListFromResponseObject:responseObject];
        
        if (list) {
            success(list);
        } else {
            NSError *error = [[NSError alloc] initWithDomain:self.manager.baseURL.absoluteString code:V2ErrorTypeGetTopicListFailure userInfo:nil];
            failure(error);
        }
    } failure:^(NSError *error) {
        failure(error);
    }];
    
    return nil;
}

//- (NSURLSessionDataTask *)getTopicListWithNodeId:(NSString *)nodeId
//                                        nodename:(NSString *)name
//                                        username:(NSString *)username
//                                            page:(NSInteger)page
//                                         success:(void (^)(V2TopicList *list))success
//                                         failure:(void (^)(NSError *error))failure {
//    NSDictionary *parameters;
//    if (nodeId) {
//        parameters = @{
//                       @"node_id": nodeId,
//                       @"p": @(page)
//                       };
//    }
//    if (name) {
//        parameters = @{
//                       @"node_name": name,
//                       @"p": @(page)
//                       };
//    }
//    if (username) {
//        parameters = @{
//                       @"username": username,
//                       @"p": @(page)
//                       };
//    }
//    
//    return [self requestWithMethod:V2RequestMethodJSONGET URLString:@"/api/topics/show.json" parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) {
//        V2TopicList *list = [[V2TopicList alloc] initWithArray:responseObject];
//        success(list);
//    } failure:^(NSError *error) {
//        failure(error);
//    }];
//    
//}


#pragma mark - Private Methods

- (NSArray *)getNodeListFromResponseObject:(id)responseObject {
    
    NSArray *list;
    
    @autoreleasepool {
        
        
        NSString *htmlString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
        
        NSError *error = nil;
        HTMLParser *parser = [[HTMLParser alloc] initWithString:htmlString error:&error];
        
        if (error) {
            NSLog(@"Error: %@", error);
        }
        
        HTMLNode *bodyNode = [parser body];
        
        HTMLNode *myNode = [bodyNode findChildWithAttribute:@"id" matchingName:@"MyNodes" allowPartial:YES];
        NSArray *nodes = [myNode findChildrenOfClass:@"grid_item"];
        
        NSMutableArray *nodesArray = [[NSMutableArray alloc] init];
        
        [nodes enumerateObjectsUsingBlock:^(HTMLNode *node, NSUInteger idx, BOOL *stop) {
            //            NSLog(@"string:\n%@", node.allContents);
            HTMLNode *numberNode = [node findChildTag:@"span"];
            NSString *nodeName = [node.allContents stringByReplacingOccurrencesOfString:numberNode.allContents withString:@""];
            nodeName = [nodeName stringByReplacingOccurrencesOfString:@" " withString:@""];
            NSString *regex1 = @"href=\"/go/(.*?)\"";
            NSString *nodeIdString = [node.rawContents stringByMatching:regex1];
            nodeIdString = [nodeIdString stringByReplacingOccurrencesOfString:@"href=\"/go/" withString:@""];
            nodeIdString = [nodeIdString stringByReplacingOccurrencesOfString:@"\"" withString:@""];
            
            NSDictionary *nodeDict = @{
                                       @"name": nodeName,
                                       @"title": nodeIdString
                                       };
            [nodesArray addObject:nodeDict];
        }];
        
        list = nodesArray;
    }
    
    return list;
}


@end
